C......................... FLIP_PC ..................................
C...... These routines are for processing the commands on DOS batch run files 
C:::::::::::::::::::::GET_INOUT_FILES::::::::::::::::::::::::::::::::::::
C.... This routine is used to extract and open input and output files from
C.... a FLIP model control file (eg.F1990075.BAT).
C.... Original written by Xiang Zhao in 2001. 
C.... Modified by PGR December 2014. Updated comments and changed logic of 
C.... IF block beginning at statement number 55
C.... This routine is called from OPEN_FILE().
C.... Each I/O file and its unit number is contained in line like 
C.... $ASSIGN FR07-Den-Temp-Eq-60S300E-HWM07-SEE2.txt FOR004 !...
C....
      SUBROUTINE GET_INOUT_FILES(INUNIT,FLAG)     
      INTEGER        INUNIT                  !... Input unit in
      INTEGER        FLAG                    !... 0:polwinds;1:equwinds;2:dhdu                     
      INTEGER        OUTUNIT                 !... Output unit for debugging
      CHARACTER*200  CH_ARRAY                !... Character array
      CHARACTER*60   DIR                     !... Directory name 
      CHARACTER*60   FILENAME                !... File name extracted
      CHARACTER*10   UNIT                    !... Unit string extracted
      INTEGER        UNITNO                  !... Unit number
      INTEGER        LENGTH                  !... length of unit string 
      INTEGER        DIRFLAG                 !... flag to indicate directory
      INTEGER        DIRLEN                  !... directory length
      INTEGER        IOFILES                 !... Indicates if a file is in use
      COMMON/FFILES/IOFILES(199)             !... Indicates files in FLIP use  
      DATA IOFILES/199*0/
      DATA OUTUNIT/0/   !..change to 100 for debug writes 
      
C------ Outer loop to read a line from the file
 50   READ(INUNIT,'(A200)',END=60) CH_ARRAY  !... read line
        DIRFLAG=0  !... initialize directory flag
      
        !... skip over any starting blanks and blank lines
        DO I=1,100
          IF (CH_ARRAY(I:I).NE.' ') GOTO 55
        ENDDO
        GOTO 50  !.. Nothing on line, so get the next line from file

        !... identify the lines containing a $ sign and read to first blank space.
 55     IF(CH_ARRAY(I:I).EQ.'$') THEN
           DO I1=I+1,100
              IF (CH_ARRAY(I1:I1).NE.' ') GOTO 57 
           ENDDO
      
           !... check if the line assigns a file
 57        IF(CH_ARRAY(I1:I1+6).EQ.'ASSIGN'.OR.CH_ARRAY(I1:I1+6).EQ.
     >     'assign') THEN
              I1=INDEX(CH_ARRAY,'ASSIGN')
           !... check if the line contains "IF", "EQWIND","THEN" or not
           ELSE IF (FLAG.EQ.1.AND.INDEX(CH_ARRAY,'IF').NE.0.AND.
     >        INDEX(CH_ARRAY,'EQWIND').NE.0.AND.
     >        INDEX(CH_ARRAY,'THEN').NE.0.AND.
     >        INDEX(CH_ARRAY,'ASSIGN').NE.0) THEN
              I1=INDEX(CH_ARRAY,'ASSIGN')
           ELSE
              GOTO 50
           ENDIF   !..end if checking "assign"
               
           !.. Skip over blank spaces
           DO J=I1+7,100 
              IF (CH_ARRAY(J:J).NE.' ') GOTO 80
           ENDDO
 80        CONTINUE 
       
           !... use ":" to identify if there is a directory before the file name
           DO K=J,100
             IF (CH_ARRAY(K:K).EQ.':')THEN
                DIRFLAG=1
                GOTO 86
             ENDIF
           ENDDO
           K=J

           !...  find out directory name and length
 86        IF(K.GT.J) THEN
              DIR=CH_ARRAY(J:K-1)
              DIRLEN=K-J
              IF (OUTUNIT.EQ.100) WRITE(OUTUNIT,*)'DIR=',DIR
           ELSE
              DIR=''
              DIRLEN=0
           ENDIF

           !.. Skip over blank spaces
           DO K1=K,100
              IF (CH_ARRAY(K1:K1).EQ.' ') GOTO 90
           ENDDO

           !...  add directory name to the file name                
 90        IF (DIRFLAG.EQ.1) THEN   
              FILENAME(1:DIRLEN)=DIR
              FILENAME(1+DIRLEN:1+DIRLEN)='\'
              FILENAME(1+DIRLEN+1:)=CH_ARRAY(K+1:K1-1)
           ELSE
              FILENAME(1:)=CH_ARRAY(K:K1-1)
           ENDIF

           IF (OUTUNIT.EQ.100) WRITE(OUTUNIT,*)'FILENAME=',FILENAME 

           !.. Skip over blank spaces to find 'FORnnn'
           DO L=K1,100
             IF (CH_ARRAY(L:L).NE.' ') GOTO 100
           ENDDO

 100       DO M=L,100
              IF (CH_ARRAY(M:M).EQ.' ') GOTO 110
           ENDDO

           !... extract unit number
 110       UNIT=CH_ARRAY(L+3:M-1)
           LENGTH=M-1-L-3+1
           IF (OUTUNIT.EQ.100) WRITE(OUTUNIT,*) 'UNIT=',UNIT

           !... convert unit from string to integer
           CALL CHAR_TO_INTEGER(UNIT,LENGTH,UNITNO)        
           IOFILES(UNITNO)=1         !.. indicates file exists
           
           !... open file with assigned unit number. Note unit 2 and 99
           !... is assigned to binary files
           IF (UNITNO.EQ.2) THEN
              OPEN(UNITNO,FILE=FILENAME,FORM='UNFORMATTED')
           ELSEIF (UNITNO.GT.90.AND.UNITNO.LT.100) THEN
              OPEN(UNITNO,FILE=FILENAME,STATUS='OLD',
     >            FORM='UNFORMATTED',ERR=300)
              GOTO 50
 300          CONTINUE !.. trap for FOR099 continue file not existing 
           ELSE
               OPEN(UNITNO,FILE=FILENAME)
           ENDIF
        ENDIF      !..end of if with checking "$"
     
      GOTO 50  !.. End outer loop to read a line from the file
 60   RETURN
      END
C:::::::::::::::::::::CHAR_TO_INTEGER::::::::::::::::::::::::::::::::::::
C.... This routine converts a string to integer. Called by GET_INOUT_FILES().
C.... Original written by Xiang Zhao in 2001. Comments added and the 
C.... extraction of the unit number was modified by PGR in December 2014.
      SUBROUTINE CHAR_TO_INTEGER(INCHAR,  !.. Input string
     >                           LENGTH,  !.. Length of string in 
     >                           OUTINT)  !.. OUTPUT: integer of INCHAR
      CHARACTER*10 INCHAR    ! input string
      INTEGER      OUTINT    ! converted integer
      INTEGER      DIGIT     ! each digit in string
      M=LENGTH
      OUTINT=0
      !... get each digit and convert to integer
      DO I=1,LENGTH
        DIGIT=ICHAR(INCHAR(I:I))-48
        M=M-1        
        OUTINT=OUTINT+DIGIT*(10**M)        
        !..WRITE(6,'(I6,2X,A,9I6)') I,INCHAR,DIGIT,OUTINT
      ENDDO
      RETURN
      END                                                              
C:::::::::::::::::::::OPEN_FILE::::::::::::::::::::::::::::::::::::
C.... This routine is responsible for processing control file(eg.W1990075.bat)
C.... specified in first argument.
C.... after opening the control file,this routine calls GET_INOUT_FILES()
C.... to extract all I/O files from the control file and open them with associated 
C.... unit numbers.
C.... Finally,this routine calls GET_CONTR_PARAMS() to extract some paramter 
C.... values from control file and write them to a file associated with unit 5.
      SUBROUTINE OPEN_FILE() 
      INTEGER       INPUT           !Input unit for control file
      INTEGER       OUTPUT          !Output unit for log file
	  INTEGER       DATAUNIT        !Unit number for data file
	  CHARACTER*60  ARG_1           !First command line argument
	  CHARACTER*60  FILENAME        !User input file name
	  CHARACTER     ANSWER1         !User input for "y"or "n"
	  CHARACTER*60  ARG_2           !Second command line argument
	  INTEGER       FLAG            !0:polwinds;1:equwinds;2:dhdu
	
      !... the following three lines are not standard Fortran 
      INTEGER(2) n1, status         !n1:indicate which command line argument
                                    !status: needed by GETARG()
      !... get first command line argument
      n1 = 1                     
      CALL GETARG(n1, ARG_1) 
	  FILENAME=ARG_1 
      !... get second command line argument
      n2 = 2
      CALL GETARG(n2,ARG_2)
      FLAG=0
      IF(INDEX(ARG_2,'EQWIND').NE.0) THEN
	    FLAG=1
      ELSE IF (INDEX(ARG_2,'DHDU-NORTH').NE.0) THEN
	    FLAG=2
      ELSE IF (INDEX(ARG_2,'DHDU-SOUTH').NE.0) THEN
	    FLAG=3
	  ENDIF  
		         	      
      !... open input control file
  	  INPUT=49                      
      OPEN(INPUT,FILE=FILENAME,STATUS='OLD',ERR=350) 	
      !...extract I/O files and their unit numbers from .RUN file 
	
	  CALL GET_INOUT_FILES(INPUT,FLAG)
	
      !... rewind .RUN file and extract parameters from it and  
      !... store these parameters into the file which is associated with unit 5
	  REWIND(INPUT)
      CALL GET_CONTR_PARAMS(INPUT,5)
	  REWIND(5)
	  GO TO 400
	    
 350  WRITE(*,*) 'FILE', FILENAME ,'NOT EXIST!'
 400  CLOSE(INPUT)
      END
C:::::::::::::::::::::GET_CONTR_PARAMS::::::::::::::::::::::::::::::::::::
C....... This routine is used to extract control parameter values from
C....... control file(eg.FYYYYDDD.RUN or FLIPRINT.RUN) and write them into files
C....... instead of input from keyboard. 
C....... Use &=START=& and &=END=& to identify the range of data.
C....... Use ! to identify the data in a line
C....... This routine is called in the OPEN_FILE() routine.

      SUBROUTINE GET_CONTR_PARAMS(INUNIT,OUTUNIT)
      INTEGER INUNIT                 ! Input unit 
      INTEGER OUTUNIT                ! Output unit 
         
      CHARACTER*200 LINE             ! Line buffer
      
      !... read each line from input file until find out flag
  50    READ(INUNIT,'(A200)',END=100) LINE
      DO I=1,200
        IF(INDEX(LINE,'&=START=&').NE.0) GO TO 60 
      ENDDO
      GO TO 50
      !... parse the line and pick out the data
  60  READ(INUNIT,'(A200)',END=100) LINE
      
      !... if meet end flag,return
      IF(INDEX(LINE,'&=END=&').NE.0) GO TO 100
      !... use "!" as a flag to identify data
      I1=INDEX(LINE,'!')
      !... output data into output file
      IF(I1.NE.0) THEN
         WRITE(OUTUNIT,*) LINE(1:I1-1)
      ENDIF    
      GO TO 60  
  100 RETURN 
      END
C::::::::::::::::::::::: PC_CLOSE :::::::::::::::::
C...... This routine for PC version of FLIP. 
      SUBROUTINE PC_CLOSE(UNIT)
      INTEGER UNIT
      REWIND(UNIT)
      RETURN
      END